package tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.rmi.UnexpectedException;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import src.UserAccount;

@SuppressWarnings("unused")
public class TestUserAccount {

	private UserAccount objectOfClassUnderTest;

	@Before
	public void setUp() throws Exception {
		objectOfClassUnderTest = new UserAccount("Some Name",
				"Some Identifier", "Some@Mail.de");
	}

	@After
	public void tearDown() throws Exception {
		objectOfClassUnderTest = null;
		System.gc();
	}

	@Test
	public void testConstructorWithNullArguments() throws Exception {
		try {
			new UserAccount(null, null, null);
			fail("A NullPointerException should be thrown!");
		} catch (NullPointerException exception) {

		}

		try {
			new UserAccount(null, "a", "a@a.de");
			fail("A NullPointerException should be thrown!");
		} catch (NullPointerException exception) {

		}

		try {
			new UserAccount("a", "a", null);
			fail("A NullPointerException should be thrown!");
		} catch (NullPointerException exception) {

		}

		try {
			new UserAccount("a", null, "a@a.de");
			fail("A NullPointerException should be thrown!");
		} catch (NullPointerException exception) {

		}
	}

	@Test
	public final void testNameProperty() {
		assertEquals(
				"User accounts name property was not as specified in constructor!",
				"Some Name", objectOfClassUnderTest.getName());
		objectOfClassUnderTest.setName("Some new name");
		assertEquals(
				"Either getName or setName of class UserAccount does not behave correctly!",
				"Some new name", objectOfClassUnderTest.getName());
	}

	@Test
	public void testSetNameWithNullArgument() throws Exception {
		try {
			objectOfClassUnderTest.setName(null);
			fail("A NullPointerException should be thrown!");
		} catch (NullPointerException exception) {

		}
	}

	@Test
	public final void testIdentifierProperty() {
		assertEquals(
				"User accounts identifier property was not as specified in constructor!",
				"Some Identifier", objectOfClassUnderTest.getIdentifier());
	}

	@Test
	public final void testMailProperty() {
		assertEquals(
				"User accounts e-mail property was not as specified in constructor!",
				"Some@Mail.de", objectOfClassUnderTest.getEMail());
		objectOfClassUnderTest.setEMail("some@new.mail");
		assertEquals(
				"Either getEMail or setEMail of class UserAccount does not behave correctly!",
				"some@new.mail", objectOfClassUnderTest.getEMail());
	}

	@Test
	public void testSetEMailWithNullArgument() throws Exception {
		try {
			objectOfClassUnderTest.setEMail(null);
			fail("A NullPointerException should be thrown!");
		} catch (NullPointerException exception) {

		}
	}

	@SuppressWarnings("deprecation")
	@Test
	public void testAccumulatedOverdraftFeeProperty() throws Exception {
		assertEquals("Accumulated overdraft fee of new account was not null!",
				0.0, objectOfClassUnderTest.getAccumulatedOverdraftFee());
		objectOfClassUnderTest.addToAccumulatedOverdraftFee(1.0);
		assertEquals(
				"Addition to accumulated overdraft fee works not correctly!",
				1.0, objectOfClassUnderTest.getAccumulatedOverdraftFee());
		objectOfClassUnderTest.subtractFromAccumulatedOverdraftFee(1.0);
		assertEquals(
				"Subtraction from accumulated overdraft fee works not correctly!",
				0.0, objectOfClassUnderTest.getAccumulatedOverdraftFee());
	}

	@Test
	public void testAddToAccumulatedOverdraftFeeWithNegativeAmount()
			throws Exception {
		try {
			this.objectOfClassUnderTest.addToAccumulatedOverdraftFee(-1.0);
			fail("The method addToAccumlatedOverdraftFee should terminate with an IllegalArgumentException if called with a negative value!");
		} catch (IllegalArgumentException exception) {

		}
	}

	@Test
	public void testSubtractFromAccumulatedOverdraftFeeWithNegativeAmount()
			throws Exception {
		try {
			this.objectOfClassUnderTest
					.subtractFromAccumulatedOverdraftFee(-1.0);
			fail("The method subtractFromAccumlatedOverdraftFee should terminate with an IllegalArgumentException if called with a negative value!");
		} catch (IllegalArgumentException exception) {

		}
	}

	@Test
	public void testEquals() throws Exception {
		assertTrue("Equallity of user accounts does not work!",
				objectOfClassUnderTest.equals(new UserAccount("Some Name",
						"Some Identifier", "Some@Mail.de")));
	}
}
